/*
 * Copyright (c) 2020-2099 the original author or authors. All rights reserve.
 */
package org.tianyun.cloud.amqp.rabbitmq.producer;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Proxy;
import java.util.Objects;

/**
 * RabbitProducerFactoryBean
 *
 * @auther ebert_chan
 */
public class RabbitProducerFactoryBean implements FactoryBean<Object>, ApplicationContextAware, InitializingBean {

    private ApplicationContext applicationContext;

    private Class<?> type;

    private String exchange;

    private String rabbitTemplate;

    /*
     * @see org.springframework.beans.factory.FactoryBean#getObject()
     */
    @Override
    public Object getObject() throws Exception {
        Object proxy = Proxy.newProxyInstance(RabbitProducerFactoryBean.class.getClassLoader(), new Class[]{type}, new RabbitProducerInvocationHandler(this));
        return proxy;
    }

    /*
     * @see org.springframework.beans.factory.FactoryBean#getObjectType()
     */
    @Override
    public Class<?> getObjectType() {
        return this.type;
    }

    /*
     * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /*
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    @Override
    public void afterPropertiesSet() throws Exception {
    }

    public Class<?> getType() {
        return type;
    }

    public void setType(Class<?> type) {
        this.type = type;
    }

    public String getExchange() {
        return exchange;
    }

    public void setExchange(String exchange) {
        this.exchange = exchange;
    }

    public String getRabbitTemplate() {
        return rabbitTemplate;
    }

    public void setRabbitTemplate(String rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        RabbitProducerFactoryBean that = (RabbitProducerFactoryBean) o;
        return Objects.equals(type, that.type) && Objects.equals(exchange, that.exchange) && Objects.equals(rabbitTemplate, that.rabbitTemplate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(type, exchange, rabbitTemplate);
    }

    @Override
    public String toString() {
        return new StringBuilder("RabbitProducerFactoryBean{").append("type=").append(type).append("'").append("}").toString();
    }

}
